package com.gitee.mybase.top.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.apache.commons.codec.digest.DigestUtils;

import java.util.Date;

@SuppressWarnings("ALL")
public class JwtUtil {

    /**
     * 校验token是否正确
     * @param token 密钥
     * @param secret 用户的密码
     * @return 是否正确
     */

    public static boolean verify(String token){
        try {
            Algorithm algorithm = Algorithm.HMAC256(encrypt(getJti(token),getSubject(token)));
            String username = getSubject(token);
            JWTVerifier verifier = JWT.require(algorithm).withSubject(username).build();
            DecodedJWT jwt = verifier.verify(token);
            return true;
        } catch (Exception exception) {
            exception.printStackTrace();
            return  false;
        }
    }

    /**
     * 获得token中的信息
     * @return token中包含的用户名
     */
    public static String getSubject(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getSubject();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    /**
     * 获得token中唯一标识
     * @param token
     * @return
     */
    public static String getJti(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getId();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    /**
     * 获得token类型
     * @param token
     * @return
     */
    public String getType(String token){
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("type").asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }


    /**
     * 生成签名,加时间过期
     * @param  secret 私钥
     * @param  subject 受众
     * @param  iat 签发时间
     * @param  exp 过期时间
     * @param  nbf 生效时间
     * @param  nbf 类型
     * @return token
     */
    public static String sign(final String secret,
                              final String subject,
                              final Date iat,
                              final Date exp,
                              final Date nbf,
                              final String type) throws Exception {

        Algorithm algorithm = Algorithm.HMAC256(encrypt(secret, subject));
        return JWT.create().withSubject(subject)
                           .withIssuedAt(iat)
                           .withJWTId(secret)
                           .withExpiresAt(exp)
                           .withNotBefore(nbf)
                           .withClaim("type", type)
                           .sign(algorithm);
    }

    public static String encrypt (String password, String secret){
        return DigestUtils.md5Hex(DigestUtils.md5Hex(password+secret));
    }

}
